package team.seekers.oj.course.service;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import team.seekers.oj.common.entity.PageResult;
import team.seekers.oj.common.enums.ApiExceptionEnum;
import team.seekers.oj.common.exception.ApiException;
import team.seekers.oj.common.util.AssertUtils;
import team.seekers.oj.course.client.GroupClient;
import team.seekers.oj.course.conventer.CourseConvertUtils;
import team.seekers.oj.course.conventer.CourseCreateReqConverter;
import team.seekers.oj.course.conventer.CourseListConverter;
import team.seekers.oj.course.conventer.CourseManageConverter;
import team.seekers.oj.course.dao.CourseDao;
import team.seekers.oj.course.dao.CourseListDao;
import team.seekers.oj.course.dto.CourseCreateReqDTO;
import team.seekers.oj.course.dto.CourseListDTO;
import team.seekers.oj.course.dto.CourseListReqDTO;
import team.seekers.oj.course.dto.CourseManageDTO;
import team.seekers.oj.course.entity.CourseDO;
import team.seekers.oj.course.entity.CourseDOField;
import team.seekers.oj.course.entity.CourseListDO;
import team.seekers.oj.lesson.dto.ChapterListDTO;

import java.util.List;

/**
 * some service methods for managing group
 *
 * @author hbc
 */
@Service
public class CourseManageService {

    @Autowired
    private CourseDao courseDao;

    @Autowired
    private CourseListDao courseListDao;

    @Autowired
    private CourseCreateReqConverter courseCreateReqConverter;

    @Autowired
    private CourseManageConverter courseManageConverter;

    @Autowired
    private CourseListConverter courseListConverter;

    @Autowired
    private GroupClient groupClient;


    public Long create(CourseCreateReqDTO reqDTO) {
        CourseDO courseDO = courseCreateReqConverter.from(reqDTO);
        courseDO.setParticipants(CourseConvertUtils.participantsFrom(reqDTO.getGroups()));
        courseDO.setParticipantNum((long) reqDTO.getGroups().size());
        AssertUtils.isTrue(courseDao.save(courseDO), ApiExceptionEnum.UNKNOWN_ERROR);

        // 增加群组参加的课程
        for (Long groupId : reqDTO.getGroups()) {
            groupClient.addGroupParticipateCourse(groupId,courseDO.getId());
        }
        return courseDO.getId();
    }

    public void delete(long courseId) {
        courseDao.removeById(courseId);
    }

    public CourseManageDTO query(long courseId) {
        CourseDO courseDO = courseDao.getById(courseId);
        AssertUtils.notNull(courseDO, ApiExceptionEnum.CONTEST_NOT_FOUND);
        return courseManageConverter.to(courseDO);
    }

    public void update(CourseManageDTO reqDTO) {
        CourseDO courseDO = courseDao.lambdaQuery().select(
                CourseDO::getId,
                CourseDO::getUserId,
                CourseDO::getVersion
        ).eq(CourseDO::getId, reqDTO.getId()).one();
        AssertUtils.notNull(courseDO, ApiExceptionEnum.CONTEST_NOT_FOUND);

        CourseDO courseUpdateDO = courseManageConverter.from(reqDTO);
        courseUpdateDO.setName(courseUpdateDO.getName());
        courseUpdateDO.setDescription(courseUpdateDO.getDescription());

        UpdateWrapper<CourseDO> updater = new UpdateWrapper<>();
        updater.eq(CourseDOField.ID, courseUpdateDO.getId());
        if (!courseDao.update(courseUpdateDO, updater)) {
            throw new ApiException(ApiExceptionEnum.SERVER_BUSY);
        }
    }

    public PageResult<CourseListDTO> page(CourseListReqDTO reqDTO) {
        LambdaQueryChainWrapper<CourseListDO> query = courseListDao.lambdaQuery()
                .orderByDesc(CourseListDO::getGmtModified);
        // 创建者id模糊查询
        if(reqDTO.getNameKey() != null){
            query.and(o2 -> o2.like(CourseListDO::getName, reqDTO.getNameKey()));
        }

        Page<CourseListDO> pageResult = query.page(new Page<>(reqDTO.getPageNow(), reqDTO.getPageSize()));
        return new PageResult<>(pageResult.getPages(), courseListConverter.to(pageResult.getRecords()));
    }

    public List<ChapterListDTO> queryChaptersSections(Long courseId) {
        CourseDO courseDO = courseDao.getById(courseId);
        AssertUtils.notNull(courseDO, ApiExceptionEnum.CONTEST_NOT_FOUND);
        return courseManageConverter.to(courseDO).getChaptersSections();
    }
}